
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>State Management - vue.js</title>
        <meta charset="utf-8">
        <meta name="description" content="Vue.js - Intuitive, Fast and Composable MVVM for building interactive interfaces.">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Roboto Mono' rel='stylesheet' type='text/css'>
        <link href='//fonts.googleapis.com/css?family=Dosis:300,500&text=Vue.js' rel='stylesheet' type='text/css'>
        <link href="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" rel='stylesheet' type='text/css'>
        <link rel="icon" href="/images/logo.png" type="image/x-icon">
        <script>
            window.PAGE_TYPE = "guide"
        </script>
        <link rel="stylesheet" href="/css/page.css">
        <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-46852172-1', 'vuejs.org');
  ga('send', 'pageview');
</script>
        <script src="/js/vue.js"></script>
    </head>
    <body>
        <div id="mobile-bar">
            <a class="menu-button"></a>
            <a class="logo" href="/"></a>
        </div>
        
            <div id="header">
  <a id="logo" href="/">
    <img src="/images/logo.png">
    <span>Vue.js <sup>2.0 RC</sup></span>
  </a>
  <span style="
    position: absolute;
    top: 100%;
    left: 60px;
    padding: 0 10px;
    background: #ef9f00;
    border-radius: 3px;
    margin-top: -15px;
    line-height: 30px;
    color: white;
    font-weight: bold;
    letter-spacing: 1px;
    box-shadow: 0 1px 2px rgba(0,0,0,.3);
  ">
    WORK IN PROGRESS
  </span>
  <ul id="nav">
    <li>
  <form id="search-form">
    <input type="text" id="search-query-nav" class="search-query st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">Guide</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">Examples</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li class="nav-dropdown-container">
  <a class="nav-link">Community</a><span class="arrow"></span>
  <ul class="nav-dropdown">
    <li><a href="https://github.com/vuejs/vue" class="nav-link" target="_blank">GitHub</a></li>
    <li><a href="http://forum.vuejs.org" class="nav-link" target="_blank">Forum</a></li>
    <li><a href="https://gitter.im/vuejs/vue" class="nav-link" target="_blank">Chat</a></li>
    <li><a href="https://twitter.com/vuejs" class="nav-link" target="_blank">Twitter</a></li>
  </ul>
</li>


  </ul>
</div>

            <div id="main">
                
                    
    <div class="sidebar">
    <ul class="main-menu">
        <li>
  <form id="search-form">
    <input type="text" id="search-query-sidebar" class="search-query st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">Guide</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">Examples</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li class="nav-dropdown-container">
  <a class="nav-link">Community</a><span class="arrow"></span>
  <ul class="nav-dropdown">
    <li><a href="https://github.com/vuejs/vue" class="nav-link" target="_blank">GitHub</a></li>
    <li><a href="http://forum.vuejs.org" class="nav-link" target="_blank">Forum</a></li>
    <li><a href="https://gitter.im/vuejs/vue" class="nav-link" target="_blank">Chat</a></li>
    <li><a href="https://twitter.com/vuejs" class="nav-link" target="_blank">Twitter</a></li>
  </ul>
</li>


    </ul>
    <div class="list">
        <div id="donate" style="margin-bottom: 20px">
            <span class="wrapper" style="width: 110px">
              <img src="/images/patreon.png">
              <a href="/support-vuejs">Support Vue.js</a>
            </span>
        </div>
        <h2>
            Guide
            <select class="version-select">
                <option value="rc" selected>2.0</option>
                <!-- !!TODO: Update value to subdomain when 2.0 is released -->
                <option value="">1.0</option>
                <option>0.12</option>
                <option>0.11</option>
            </select>
        </h2>
        <ul class="menu-root">
            
                
                
                  <li><h3>Essentials</h3></li>
                
                
                
                <li>
                    <a href="/guide/installation.html" class="sidebar-link">Installation</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/index.html" class="sidebar-link">Introduction</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/instance.html" class="sidebar-link">The Vue Instance</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/syntax.html" class="sidebar-link">Template Syntax</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/computed.html" class="sidebar-link">Computed Properties and Watchers</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/class-and-style.html" class="sidebar-link">Class and Style Bindings</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/conditional.html" class="sidebar-link">Conditional Rendering</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/list.html" class="sidebar-link">List Rendering</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/events.html" class="sidebar-link">Event Handling</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/forms.html" class="sidebar-link">Form Input Bindings</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/components.html" class="sidebar-link">Components</a>
                </li>
            
                
                
                
                  <li><h3>Advanced</h3></li>
                
                
                <li>
                    <a href="/guide/transitions.html" class="sidebar-link">Transitions: Entering, Leaving, and Lists</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/transitioning-state.html" class="sidebar-link">Transitioning State</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/render-function.html" class="sidebar-link">Render Functions</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/reactivity.html" class="sidebar-link">Reactivity in Depth</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/custom-directive.html" class="sidebar-link">Custom Directives</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/mixins.html" class="sidebar-link">Mixins</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/plugins.html" class="sidebar-link">Plugins</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/single-file-components.html" class="sidebar-link">Single File Components</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/routing.html" class="sidebar-link">Routing</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/state-management.html" class="sidebar-link current">State Management</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/unit-testing.html" class="sidebar-link">Unit Testing</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/ssr.html" class="sidebar-link">Server-Side Rendering</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/migration.html" class="sidebar-link">Migration from 1.x</a>
                </li>
            
                
                
                
                
                  <li><h3>Meta</h3></li>
                
                <li>
                    <a href="/guide/comparison.html" class="sidebar-link">Comparison with Other Frameworks</a>
                </li>
            
                
                
                
                
                <li>
                    <a href="/guide/join.html" class="sidebar-link">Join the Vue.js Community!</a>
                </li>
            
        </ul>
    </div>
</div>


<div class="content guide with-sidebar state-management-guide">
    <div id="ad">
  <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=vuejs" id="_carbonads_js"></script>
</div>

    <h1>State Management</h1>
    <h2 id="Official-Flux-Like-Implementation"><a href="#Official-Flux-Like-Implementation" class="headerlink" title="Official Flux-Like Implementation"></a>Official Flux-Like Implementation</h2><p>Large applications can often grow in complexity, due to multiple pieces of state scattered across many components and the interactions between them. To solve this problem, Vue offers <a href="https://github.com/vuejs/vuex" target="_blank" rel="external">vuex</a>: our own Elm-inspired state management library. It even integrates into <a href="https://github.com/vuejs/vue-devtools" target="_blank" rel="external">vue-devtools</a>, providing zero-setup access to time travel.</p>
<h3 id="Information-for-React-Developers"><a href="#Information-for-React-Developers" class="headerlink" title="Information for React Developers"></a>Information for React Developers</h3><p>If you’re coming from React, you may be wondering how vuex compares to <a href="https://github.com/reactjs/redux" target="_blank" rel="external">redux</a>, the most popular Flux implementation in that ecosystem. Redux is actually view-layer agnostic, so it can easily be used with Vue via some <a href="https://github.com/egoist/revue" target="_blank" rel="external">simple bindings</a>. Vuex is different in that it <em>knows</em> it’s in a Vue app. This allows it to better integrate with Vue, offering a more intuitive API and improved development experience.</p>
<h2 id="Simple-State-Management-from-Scratch"><a href="#Simple-State-Management-from-Scratch" class="headerlink" title="Simple State Management from Scratch"></a>Simple State Management from Scratch</h2><p>It is often overlooked that the source of truth in Vue applications is the raw <code>data</code> object - a Vue instance simply proxies access to it. Therefore, if you have a piece of state that should be shared by multiple instances, you can simply share it by identity:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">const</span> sourceOfTruth = &#123;&#125;</div><div class="line"></div><div class="line"><span class="keyword">const</span> vmA = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  data: sourceOfTruth</div><div class="line">&#125;)</div><div class="line"></div><div class="line"><span class="keyword">const</span> vmB = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  data: sourceOfTruth</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p>Now whenever <code>sourceOfTruth</code> is mutated, both <code>vmA</code> and <code>vmB</code> will update their views automatically. Subcomponents within each of these instances would also have access via <code>this.$root.$data</code>. We have a single source of truth now, but debugging would be a nightmare. Any piece of data could be changed by any part of our app at any time, without leaving a trace.</p>
<p>To help solve this problem, we can adopt a simple <strong>store pattern</strong>:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">var</span> store = &#123;</div><div class="line">  debug: <span class="literal">true</span>,</div><div class="line">  state: &#123;</div><div class="line">    message: <span class="string">'Hello!'</span></div><div class="line">  &#125;,</div><div class="line">  setMessageAction (newValue) &#123;</div><div class="line">    <span class="keyword">this</span>.debug &amp;&amp; <span class="built_in">console</span>.log(<span class="string">'setMessageAction triggered with'</span>, newValue)</div><div class="line">    <span class="keyword">this</span>.state.message = newValue</div><div class="line">  &#125;,</div><div class="line">  clearMessageAction () &#123;</div><div class="line">    <span class="keyword">this</span>.debug &amp;&amp; <span class="built_in">console</span>.log(<span class="string">'clearMessageAction triggered'</span>)</div><div class="line">    <span class="keyword">this</span>.state.message = <span class="string">'action B triggered'</span></div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>Notice all actions that mutate the store’s state are put inside the store itself. This type of centralized state management makes it easier to understand what type of mutations could happen and how are they triggered. When something goes wrong, we’ll also now have a log of what happened leading up to the bug.</p>
<p>In additon, each instance/component can still own and manage its own private state:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">var</span> vmA = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  data: &#123;</div><div class="line">    privateState: &#123;&#125;,</div><div class="line">    sharedState: store.state</div><div class="line">  &#125;</div><div class="line">&#125;)</div><div class="line"></div><div class="line"><span class="keyword">var</span> vmB = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  data: &#123;</div><div class="line">    privateState: &#123;&#125;,</div><div class="line">    sharedState: store.state</div><div class="line">  &#125;</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p><img src="/images/state.png" alt="State Management"></p>
<p class="tip">It’s important to note that you should never replace the original state object in your actions - the components and the store need to share reference to the same object in order for mutations to be observed.</p>

<p>As we continue developing the convention where components are never allowed to directly mutate state that belongs to a store, but should instead dispatch events that notify the store to perform actions, we eventually arrive at the <a href="https://facebook.github.io/flux/" target="_blank" rel="external">Flux</a> architecture. The benefit of this convention is we can record all state mutations happening to the store and implement advanced debugging helpers such as mutation logs, snapshots, and history re-rolls / time travel.</p>
<p>This brings us full circle back to <a href="https://github.com/vuejs/vuex" target="_blank" rel="external">vuex</a>, so if you’ve read this far it’s probably time to try it out!</p>

    
      <div class="guide-links">
        
          <span>← <a href="/guide/routing.html">Routing</a></span>
        
        
          <span style="float:right"><a href="/guide/unit-testing.html">Unit Testing</a> →</span>
        
      </div>
    
    <div class="footer">
      Caught a mistake or want to contribute to the documentation?
      <a href="https://github.com/vuejs/vuejs.org/blob/master/src/guide/state-management.md" target="_blank">
        Edit this page on Github!
      </a>
    </div>
</div>

                
            </div>
            <script src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
            <script src="/js/smooth-scroll.min.js"></script>
            <script src="/js/common.js"></script>
        

        <script src="//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js"></script><script src="https://cdn.jsdelivr.net/gh/shentao/vuejs-outdated-docs-modal@v1.3/prompt.min.js"></script>
        <script>
            document.addEventListener('DOMContentLoaded', function() {
                FastClick.attach(document.body);
            }, false);
        </script>
    </body>
</html>
